#include <iostream>
#include <memory>

using namespace std;
class AbstractProductA
{
public:
    virtual void show() = 0;
    ~AbstractProductA() {}
};
class AbstractProductB
{
public:
    virtual void show() = 0;
    ~AbstractProductB() {}
};
class ProductA1 : public AbstractProductA
{
public:
    virtual void show() override
    {
        cout << "void ProductA1::show()" << endl;
    }
};
class ProductA2 : public AbstractProductA
{
public:
    virtual void show() override
    {
        cout << "void ProductA2:: show()" << endl;
    }
};
class ProductB1 : public AbstractProductB
{
public:
    virtual void show() override
    {
        cout << "void ProductB1::show()" << endl;
    }
};
class ProductB2 : public AbstractProductB
{
public:
    virtual void show() override
    {
        cout << "void ProductB2::show()" << endl;
    }
};
class AbstractFactory
{
public:
    virtual AbstractProductA *createProductA() = 0;
    virtual AbstractProductB *createProductB() = 0;
    ~AbstractFactory() {}
};
class ConcreateFactory1 : public AbstractFactory
{
public:
    AbstractProductA *createProductA() override
    {
        return new ProductA1();
    }
    AbstractProductB *createProductB() override
    {
        return new ProductB1();
    }
};
class ConcreateFactory2 : public AbstractFactory
{
public:
    AbstractProductA *createProductA() override
    {
        return new ProductA2();
    }
    AbstractProductB *createProductB() override
    {
        return new ProductB2();
    }
};

void test()
{
    AbstractFactory *factory1 = new ConcreateFactory1();
    AbstractProductA *productA = factory1->createProductA();
    AbstractProductB *productB = factory1->createProductB();
    productA->show();
    productB->show();

    cout << endl;
    AbstractFactory *factory2 = new ConcreateFactory2();
    productA = factory2->createProductA();
    productB = factory2->createProductB();
    productA->show();
    productB->show();
}
int main()
{
    test();
    return 0;
}
